package com.kai.steering.data.service.service.impl;

import com.kai.steering.common.web.vo.ReturnCodeExt;
import com.kai.steering.data.service.databus.enums.UsableEnum;
import com.kai.steering.data.service.entity.domainObject.KnowledgeDO;
import com.kai.steering.data.service.entity.domainObject.TestDO;
import com.kai.steering.data.service.entity.domainObject.WarehouseDO;
import com.kai.steering.data.service.entity.domainObject.WarehouseTestDO;
import com.kai.steering.data.service.entity.dto.WarehouseQueryDTO;
import com.kai.steering.data.service.entity.po.Warehouse;
import com.kai.steering.data.service.entity.po.WarehouseTest;
import com.kai.steering.data.service.entity.vo.WarehouseVO;
import com.kai.steering.data.service.mapper.WarehouseMapper;
import com.kai.steering.data.service.mapper.WarehouseTestMapper;
import com.kai.steering.data.service.service.KnowledgeService;
import com.kai.steering.data.service.service.TestService;
import com.kai.steering.data.service.service.WarehouseService;
import com.kai.steering.common.web.service.impl.BaseServiceImpl;
import com.kai.steering.common.vo.Page;

import com.kai.steering.data.service.service.WarehouseTestService;
import com.kai.steering.data.service.util.EqualsUtil;
import com.kai.steering.exception.ExcelException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import org.springframework.web.multipart.MultipartFile;

/**
 * <pre>
 * 仓库 服务实现类
 * </pre>
 *
 * @author kai
 * @since 2022-02-23
 */
@Slf4j
@Service
public class WarehouseServiceImpl extends BaseServiceImpl<WarehouseMapper, Warehouse> implements WarehouseService {

    @Autowired
    private WarehouseMapper warehouseMapper;
    @Autowired
    WarehouseTestMapper warehouseTestMapper;
    @Autowired
    KnowledgeService knowledgeService;
    @Autowired
    TestService testService;
    @Autowired
    WarehouseTestService warehouseTestService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    /**
     * 保存仓库
     * 参数：
     *  warehouseDO
     */
    public WarehouseDO saveWarehouse(WarehouseDO warehouseDO) {
        /**
         * 参数校验
         */
        //id
        if (StringUtils.isNotEmpty(warehouseDO.getWarehouseId())) {
            warehouseDO.setWarehouseId(null);
        }
        //warehouseSuperior
        WarehouseDO warehouseSuperior = null;
        if (!StringUtils.isEmpty(warehouseDO.getWarehouseSuperior())) {
            warehouseSuperior = getWarehouseById(warehouseDO.getWarehouseSuperior(), null);
            if (warehouseSuperior == null || StringUtils.isEmpty(warehouseSuperior.getWarehouseId())) {
                throw ReturnCodeExt.BUSINESS_EXCEPTION.getException(warehouseDO.getWarehouseSuperior() + "不存在");
            }
        }

        /**
         * 搭建po对象
         */
        Warehouse warehouse = new Warehouse(warehouseDO);
        warehouse.setCreationDatetime(new Date());
        //级别
        if (StringUtils.isEmpty(warehouseDO.getWarehouseSuperior())) {
            warehouse.setLevel(0);
        } else {
            warehouse.setLevel(warehouseSuperior.getLevel() + 1);
        }
        //添加人


        /**
         * 调用服务
         */
        boolean save = super.save(warehouse);
        /**
         * 搭建DO对象
         */
        WarehouseDO warehouseSave = warehouseDO.convertWarehouseDO(warehouse);
        return warehouseSave;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    /**
     * 修改仓库
     * 参数：
     *  Serializable id
     *  WarehouseDO warehouseDO
     */
    public WarehouseDO updateWarehouse(Serializable id, WarehouseDO warehouseDO) {
        /**
         * 参数验证
         */
        //id
        WarehouseDO oldWarehouseDO = getWarehouseById(id, null);
        if (oldWarehouseDO == null || StringUtils.isEmpty(oldWarehouseDO.getWarehouseId())) {
            throw ReturnCodeExt.BUSINESS_EXCEPTION.getException(warehouseDO.getWarehouseSuperior() + "不存在");
        }
        //warehouseSuperior
        if (StringUtils.isNotEmpty(warehouseDO.getWarehouseSuperior())) {
            WarehouseDO warehouseSuperior = getWarehouseById(warehouseDO.getWarehouseSuperior(), null);
            if (warehouseSuperior == null || StringUtils.isEmpty(warehouseSuperior.getWarehouseId())) {
                throw ReturnCodeExt.BUSINESS_EXCEPTION.getException("上级" + warehouseDO.getWarehouseSuperior() + "不存在");
            }
        }
        /**
         * 构建对象
         */
        Warehouse warehouse = new Warehouse(warehouseDO);
        boolean b = super.updateById(warehouse);
        if (b == false) {
            return null;
        }
        warehouseDO.convertWarehouseDO(warehouse);
        return warehouseDO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    /**
     * 删除仓库
     * 参数：
     *  Serializable id
     */
    public boolean deleteWarehouse(Serializable id) {
        WarehouseDO oldWarehouseDO = getWarehouseById(id, null);
        if (oldWarehouseDO == null || !StringUtils.isNotEmpty(oldWarehouseDO.getWarehouseId())) {
            throw ReturnCodeExt.BUSINESS_EXCEPTION.getException(id + "不存在");
        }
        boolean b = super.removeById(id);
        return b;
    }

    @Override
    /**
     * 获取仓库详情
     * Serializable id
     * boolean subordinateExist
     * boolean knowledgeExist
     * boolean testExist
     */
    public WarehouseDO getWarehouseById(Serializable id, HashMap<String, Boolean> parameterMap) {

        Warehouse warehouse = super.getById(id);
        WarehouseDO warehouseDO = new WarehouseDO(warehouse);

        if (parameterMap != null) {

            //是否获取下级仓库
            if (EqualsUtil.objectBooleanEquals(parameterMap.get("subordinateExist"))) {
                List<WarehouseDO> warehouseDOS = childWarehouse(id.toString(), parameterMap);
                warehouseDO.setChildWarehouses(warehouseDOS);

            }

            if (EqualsUtil.objectBooleanEquals(parameterMap.get("knowledgeExist")) && warehouse.getKnowledgeId() != null) {
                List<String> knowledgeIds = Arrays.asList(StringUtils.splitByWholeSeparator(warehouse.getKnowledgeId(), ","));
                List<KnowledgeDO> knowledgeByIds = knowledgeService.getKnowledgeByIds(knowledgeIds);
                warehouseDO.setKnowledges(knowledgeByIds);
            }
            if (EqualsUtil.objectBooleanEquals(parameterMap.get("testExist"))) {
                ArrayList<WarehouseTest> warehouseTestByWarehouseId = warehouseTestMapper.getWarehouseTestByWarehouseId(id.toString());
                List<TestDO> testByWarehouseTest = testService.getTestByWarehouseTest(warehouseTestByWarehouseId);
                warehouseDO.setTestS(testByWarehouseTest);
            }

        }
        return warehouseDO;
    }

    public List<TestDO> getWarehouseTestById(Serializable id) {
        ArrayList<WarehouseTest> warehouseTestByWarehouseId = warehouseTestMapper.getWarehouseTestByWarehouseId(id.toString());
        List<TestDO> testByWarehouseTest = testService.getTestByWarehouseTest(warehouseTestByWarehouseId);

        return testByWarehouseTest;
    }

    @Override
    /**
     * 获取全部仓库
     */
    public List<WarehouseDO> getAllWarehouse() {
        List<Warehouse> warehouselist = warehouseMapper.selectList(new QueryWrapper<Warehouse>());
        List<WarehouseDO> result = warehouselist.stream()
                .map(warehouse -> {
                    WarehouseDO warehouseDO = new WarehouseDO();
                    BeanUtil.copyProperties(warehouse, warehouseDO);
                    return warehouseDO;
                })
                .collect(Collectors.toList());
        return result;
    }

    @Override
    /**
     * 根据参数获取仓库
     * 参数
     *  WarehouseQueryDTO warehouseQueryDTO
     */
    public Page<WarehouseVO> getWarehousePageList(WarehouseQueryDTO warehouseQueryDTO) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page = setPageParam(
                warehouseQueryDTO, OrderItem.desc("creation_datetime")
        );

        QueryWrapper<Warehouse> queryWrapper = new QueryWrapper<>();
        //存在
        queryWrapper.eq("usable", UsableEnum.ACTIVE.getCode());
        //id
        if (StringUtils.isNotEmpty(warehouseQueryDTO.getWarehouseId())) {
            queryWrapper.eq("warehouse_id", warehouseQueryDTO.getWarehouseId());
        }
        //仓库名
        if (StringUtils.isNotEmpty(warehouseQueryDTO.getWarehouseName())) {
            queryWrapper.like("warehouse_name", warehouseQueryDTO.getWarehouseName());
        }
        //上级仓库
        if (StringUtils.isNotEmpty(warehouseQueryDTO.getWarehouseSuperior())) {
            queryWrapper.eq("warehouse_superior", warehouseQueryDTO.getWarehouseSuperior());
        }
        //仓库信息
        if (StringUtils.isNotEmpty(warehouseQueryDTO.getWarehouseInformation())) {
            queryWrapper.like("warehouse_information", warehouseQueryDTO.getWarehouseInformation());
        }
        //管理员id或者用户id
        if (StringUtils.isNotEmpty(warehouseQueryDTO.getFounder())) {
            queryWrapper.eq("founder", warehouseQueryDTO.getFounder());
        }
        //级别
        if (warehouseQueryDTO.getLevel() != null) {
            queryWrapper.eq("level", warehouseQueryDTO.getLevel());
        }
        //知识点分类
        if ((warehouseQueryDTO.getKnowledges()) != null) {
            queryWrapper.in("knowledge_id", warehouseQueryDTO.getKnowledges());
        }

        //开始时间 创建
        if (warehouseQueryDTO.getCreationDateOrigin() != null) {
            queryWrapper.ge("creation_datetime", warehouseQueryDTO.getCreationDateOrigin());
        }
        //结束时间 创建
        if (warehouseQueryDTO.getCreationDateTerminus() != null) {
            queryWrapper.le("creation_datetime", warehouseQueryDTO.getCreationDateTerminus());
        }

        //组合条件
        IPage<Warehouse> entityPage = warehouseMapper.selectPage(page, queryWrapper);
        List<WarehouseVO> result = entityPage.getRecords().stream()
                .map(warehouse -> {
                    WarehouseVO warehouseVo = new WarehouseVO();
                    BeanUtil.copyProperties(warehouse, warehouseVo);
                    return warehouseVo;
                })
                .collect(Collectors.toList());

        return Page.<WarehouseVO>builder()
                .currPage(warehouseQueryDTO.getPageNo())
                .pageSize(warehouseQueryDTO.getPageSize())
                .totalCount((int) entityPage.getTotal())
                .list(result)
                .build();
    }


    @Override
    /**
     * 判断参数是否存在
     * @param key 比较属性
     * @param val 比较的值
     * @param id 比较的ID
     * @return
     */
    public boolean isExists(String key, String val, Serializable id) {
        QueryWrapper<Warehouse> qw = new QueryWrapper<>();
        qw.eq(key, val);
        if (id != null) {
            qw.ne("warehouse_id", id);
        }
        int num = this.count(qw);
        return num > 0;
    }

    @Override
    /**
     * 移动仓库
     * @param warehouseMove
     * @param warehouseId
     * @return
     */
    public boolean moveWarehouse(Serializable warehouseTarget, Serializable warehouseId) {
        /**
         * 验证参数
         */
        //warehouseMove
        WarehouseDO targetWarehouse = getWarehouseById(warehouseTarget, null);
        if (targetWarehouse == null || StringUtils.isEmpty(targetWarehouse.getWarehouseId())) {
            throw ReturnCodeExt.BUSINESS_EXCEPTION.getException(targetWarehouse + "目标仓库不存在");
        }
        //warehouseId
        WarehouseDO warehouse = getWarehouseById(warehouseId, null);
        if (warehouse == null || StringUtils.isEmpty(warehouse.getWarehouseId())) {
            throw ReturnCodeExt.BUSINESS_EXCEPTION.getException(warehouseId + "移动仓库不存在");
        }
        if (EqualsUtil.objectEquals(warehouse.getWarehouseSuperior(), warehouseTarget.toString())) {
            throw ReturnCodeExt.BUSINESS_EXCEPTION.getException("目标仓库中存在当前仓库");
        }
        /**
         * 构建对象
         */
        warehouse.setWarehouseSuperior(warehouseTarget.toString());

        /**
         * 调用服务
         */
        WarehouseDO warehouseDO = this.updateWarehouse(warehouse.getWarehouseId(), warehouse);
        return false;
    }

    @Override
    /**
     * 获取仓库树
     */
    public WarehouseDO treeWarehouse(Serializable warehouseId, HashMap<String,Boolean> parameterMap) {
        /**
         * 参数检查
         */
        //id
        parameterMap.put("subordinateExist",false);
        WarehouseDO warehouseDO = getWarehouseById(warehouseId, parameterMap);
        if (warehouseDO == null || StringUtils.isEmpty(warehouseDO.getWarehouseId())) {
            throw ReturnCodeExt.BUSINESS_EXCEPTION.getException(warehouseId + "不存在");
        }

        /**
         * 生成树
         */
        warehouseTree(warehouseDO,parameterMap);
        return warehouseDO;
    }

    @Override
    public boolean moveTestInWarehouse(Serializable warehouseTargetId, Serializable warehouseId, Serializable testId) {

        WarehouseDO warehouseTargetDO = getWarehouseById(warehouseTargetId, null);
        WarehouseDO warehouseDO = getWarehouseById(warehouseId, null);
        TestDO testById = testService.getTestById(testId, null);
        if (warehouseTargetDO == null || StringUtils.isEmpty(warehouseTargetDO.getWarehouseId())) {
            throw ReturnCodeExt.BUSINESS_EXCEPTION.getException(warehouseTargetId + "目标仓库 不存在");
        }
        if (warehouseDO == null || StringUtils.isEmpty(warehouseDO.getWarehouseId())) {
            throw ReturnCodeExt.BUSINESS_EXCEPTION.getException(warehouseId + "仓库 不存在");
        }
        if (testById == null || StringUtils.isEmpty(testById.getTestId())) {
            throw ReturnCodeExt.BUSINESS_EXCEPTION.getException(testById + "试卷 不存在");
        }
        ArrayList<String> warehouseTest = warehouseTestMapper.getWarehouseTestId(warehouseId, testId);
        if (warehouseTest == null || warehouseTest.size() < 1) {
            throw ReturnCodeExt.BUSINESS_EXCEPTION.getException(testById + "试卷 不存在 该仓库中");
        }

        ArrayList<String> warehouseTestTargetId = warehouseTestMapper.getWarehouseTestId(warehouseTargetId, testId);
        if (warehouseTestTargetId == null || warehouseTestTargetId.size() > 0) {
            throw ReturnCodeExt.BUSINESS_EXCEPTION.getException(testById + "试卷 已存在 仓库中");
        }
        boolean b = deleteAddWarehouse(warehouseTargetId, warehouseTest, testId);
        return b;
    }

    /*
        删除仓库关系、并添加仓库关系
     */
    @Transactional
    public boolean deleteAddWarehouse(Serializable warehouseTargetId, List<String> warehouseTest, Serializable testId) {
        int i = warehouseTestMapper.deleteBatchIds(warehouseTest);
        WarehouseTest warehouseTest1 = new WarehouseTest();
        int insert = warehouseTestMapper.insert(new WarehouseTest(warehouseTargetId.toString(), testId.toString()));
        if (insert > 0) {
            return true;
        }

        return false;
    }

    /**
     * 递归生成树
     */
    private WarehouseDO warehouseTree(WarehouseDO warehouseDO, HashMap<String ,Boolean>parameterMap) {
        if (warehouseDO == null) {
            return null;
        }
        List<WarehouseDO> warehouseDOS = childWarehouse(warehouseDO.getWarehouseId(), parameterMap);
        warehouseDO.setChildWarehouses(warehouseDOS);

        List<WarehouseDO> childs = warehouseDO.getChildWarehouses();
        childs.forEach(knowledgeDO1 -> {
            knowledgeDO1 = warehouseTree(knowledgeDO1, parameterMap);
        });
        return warehouseDO;
    }

    /**
     * 获取子库
     */
    private List<WarehouseDO> childWarehouse(String WarehouseId,HashMap<String,Boolean>parameterMap) {
        /**
         * 获取子仓库
         */
        List<Warehouse> warehouseList = warehouseMapper.childWarehouse(WarehouseId);


        /**
         * 转换
         */
        List<WarehouseDO> collect = warehouseList.stream().map(warehouse -> {
            WarehouseDO warehouseDO = new WarehouseDO(warehouse);
            if(parameterMap!=null){

            if (EqualsUtil.objectBooleanEquals(parameterMap.get("knowledgeExist")) && warehouse.getKnowledgeId() != null) {
                List<String> knowledgeIds = Arrays.asList(StringUtils.splitByWholeSeparator(warehouse.getKnowledgeId(), ","));
                List<KnowledgeDO> knowledgeByIds = knowledgeService.getKnowledgeByIds(knowledgeIds);
                warehouseDO.setKnowledges(knowledgeByIds);
            }
            if (EqualsUtil.objectBooleanEquals(parameterMap.get("testExist"))) {
                ArrayList<WarehouseTest> warehouseTestByWarehouseId = warehouseTestMapper.getWarehouseTestByWarehouseId(warehouse.getWarehouseId());
                List<TestDO> testByWarehouseTest = testService.getTestByWarehouseTest(warehouseTestByWarehouseId);
                warehouseDO.setTestS(testByWarehouseTest);
            }

            }
            return warehouseDO;
        }).collect(Collectors.toList());

        return collect;
    }

    public WarehouseTestDO importTest(Serializable warehouseId, MultipartFile file) {
        String testId = testService.importTest(file);
        WarehouseTestDO warehouseTestDO = new WarehouseTestDO(warehouseId.toString(), testId);
        WarehouseTestDO newWarehouseTestDO = warehouseTestService.saveWarehouse(warehouseTestDO);


        return newWarehouseTestDO;
    }

    @Override
    public void addTest(String id, TestDO testDO) {
        TestDO testDO1 = testService.saveTest(testDO);
        WarehouseTestDO warehouseTestDO = new WarehouseTestDO(id, testDO1);
        warehouseTestService.saveWarehouse(warehouseTestDO);
    }
}

